//package agenten;
//import game.Tree;
//import game.TreeBuilder;
//import jade.core.AID;
//import jade.core.Agent;
//import jade.core.behaviours.CyclicBehaviour;
//import jade.core.behaviours.SimpleBehaviour;
//import jade.domain.DFService;
//import jade.domain.FIPAException;
//import jade.domain.FIPAAgentManagement.DFAgentDescription;
//import jade.domain.FIPAAgentManagement.ServiceDescription;
//import jade.lang.acl.ACLMessage;
//import jade.lang.acl.MessageTemplate;
//
//
//@SuppressWarnings("serial")
//public class PerfectAgent extends Agent {
//	
//	private enum CurrentPlayer {
//		Max, Min
//	}
//	
//	private AID agentId = null;
//	private boolean registered = false;
//	private Tree _root = null;
//	
//	@Override
//	protected void setup() {
//		System.out.println(getLocalName()+" STARTED");
//		
//		this.agentId = new AID(getLocalName(), AID.ISLOCALNAME);
//
//		ServiceDescription sd = new ServiceDescription();
//		DFAgentDescription dfd = new DFAgentDescription();
//
//		sd.setType(ManagementAgent.SERVICEID_PERFECT_AGENT);
//		sd.setName(getName());
//
//		dfd.setName(getAID());
//		dfd.addServices(sd);
//		
//		try {
//			// Register with the Directory Facilitator (DF):
//			DFService.register(this, dfd);
//			System.out.println(getLocalName()+" registered with DF");
//		} catch (FIPAException e) {
//			System.err.println(getName() + ": Could not register with DF.");
//			doDelete(); // Kill the agent
//		}
//		
//		addBehaviour(new SimpleBehaviour(this) {
//
//			@Override
//			public void action() {
//				AID receiver = null;
//				// Get all strike agents from the Directory Facilitator (DF):
//				DFAgentDescription template = new DFAgentDescription();
//				ServiceDescription sd = new ServiceDescription();
//				sd.setType(ManagementAgent.SERVICEID_STRIKE_AGENT);
//				template.addServices(sd);
//				try {
//					DFAgentDescription[] result = DFService.search(myAgent,	template);
//					for (DFAgentDescription desc : result) {
//						receiver = desc.getName();
//					}
//				} catch (FIPAException e) {
//					System.err.println(getName() + ": Could not query the DF.");
//				}
//				
//				if (receiver != null) {
//					System.out.println(receiver+" gefunden");
//					ACLMessage registerAtMaster = new ACLMessage(ACLMessage.INFORM);
//					
//					registerAtMaster.addReceiver(receiver);
//
//					registerAtMaster.setContent(ShowMaster.REGISTER_PERFECT);
//					myAgent.send(registerAtMaster);
//					
//					registered = true;
//				}
//			}
//
//			@Override
//			public boolean done() {
//				return registered;
//			}
//		});
//		
//		addBehaviour(new CyclicBehaviour(this) {
//
//			@Override
//			public void action() {
//				MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.INFORM);
//				ACLMessage msg = myAgent.receive(mt);
//				if (msg != null) {
//					// INFORM Message received. Process it
//					String msgContent = msg.getContent();
//					if(msgContent.equals(ShowMaster.YOUR_TURN)){
//						System.out.println(getLocalName()+": it's my turn ");
//						ACLMessage registerAtMaster = new ACLMessage(ACLMessage.REQUEST);
//						
//						registerAtMaster.addReceiver(msg.getSender());
//
//						registerAtMaster.setContent(ShowMaster.REQUEST_STRIKES);
//						myAgent.send(registerAtMaster);
//					} else if (msgContent.contains("STRIKES")) {
//						int strikes = Integer.parseInt(msgContent.substring(9));
//						int move = calculateMove(strikes);
//						
//						System.out.println(getLocalName() + ": received current number of strikes: "+strikes);
//						System.out.println(getLocalName() + ": i take " + move);
//						
//						ACLMessage informMove = new ACLMessage(ACLMessage.INFORM);
//						
//						informMove.addReceiver(msg.getSender());
//
//						informMove.setContent(ShowMaster.REPLY_STRIKES + move);
//						myAgent.send(informMove);
//					}
//				} else {
//					block();
//				}
//			}
//		});
//    }
//
//	@Override
//	protected void takeDown() {
//		// Vom DF abmelden
//		try {
//			DFService.deregister(this);
//			System.out.println(getLocalName()+" DEREGISTERED WITH THE DF");
//			doDelete();
//		} catch (FIPAException e) {
//			e.printStackTrace();
//		}
//	}
//	
//	private void buildTree(int count) {
//		// Neuen Baum erstellen mit Anzahl Streichhoelzer
//		_root = new TreeBuilder(count).getTree();
//		
//		int alpha = -1; 
//		int beta = 1;
//		maxValue(_root, alpha, beta);
//	}
//	
//	// Ueberladene Funktion fuer Alpha-Beta Pruning
//	private int maxValue(Tree node, int alpha, int beta) {
//		int nodeValue;
//		
//		// Baut alle moeglichen Kinder des Knotens
//		TreeBuilder.build(node);
//		// Alle Kinder des uebergebenen Knotens
//		for (Tree child : node) {
//			// ueberpruefen ob Endknoten.
//			if (child.getData() == 0) {
//				// Endknoten evaluieren.
//				nodeValue = evaluate(child, CurrentPlayer.Min);
//			// Kein Endknoten, hat also noch Kinder.
//			} else {
//				// Kindbewertung durch Min-Methode.
//				nodeValue = minValue(child, alpha, beta);
//			}
//			
//			// Der beta-Wert ist kleiner als der aktuelle nodeValue,
//			// also fuer Min besser. Demzufolge kann abgebrochen und
//			// der beta-Wert zurueckgegeben werden.
//			if (nodeValue >= beta) {
//				node.setRating(beta);
//				return beta;
//			}
//			
//			// Der aktuelle nodeValue ist groesser als der alpha-Wert,
//			// also fuer Max besser. Der alpha-Wert wird mit dem
//			// nodeValue ueberschrieben.
//			if (nodeValue > alpha) {
//				alpha = nodeValue;
//			}
//		}
//		
//		// Alle Kinder wurden ueberprueft. Der aktuelle alpha-Wert ist
//		// der beste fuer Max und wird zurueckgegeben.
//		node.setRating(alpha);
//		return alpha;
//	}
//
//	private int minValue(Tree node, int alpha, int beta) {
//		int nodeValue;
//
//		// Baut alle moeglichen Kinder des Knotens
//		TreeBuilder.build(node);
//		// Alle Kinder des uebergebenen Knotens
//		for (Tree child : node) {
//			// ueberpruefen ob Endknoten.
//			if (child.getData() == 0) {
//				// Endknoten evaluieren.
//				nodeValue = evaluate(child, CurrentPlayer.Max);
//			// Kein Endknoten, hat also noch Kinder.
//			} else {
//				// Kindbewertung durch Max-Methode.
//				nodeValue = maxValue(child, alpha, beta);
//			}
//			
//			// Der alpha-Wert ist kleiner als der aktuelle nodeValue,
//			// also fuer Max besser. Demzufolge kann abgebrochen und
//			// der alpha-Wert zurueckgegeben werden.
//			if (nodeValue <= alpha) {
//				node.setRating(alpha);
//				return alpha;
//			}
//			
//			// Der aktuelle nodeValue ist groesser als der beta-Wert,
//			// also fuer Min besser. Der beta-Wert wird mit dem
//			// nodeValue ueberschrieben.
//			if (nodeValue < beta) {
//				beta = nodeValue;
//			}
//		}
//		
//		// Alle Kinder wurden ueberprueft. Der aktuelle beta-Wert ist
//		// der beste fuer Min und wird zurueckgegeben.
//		node.setRating(beta);
//		return beta;
//	}
//	
//	private int evaluate(Tree node, CurrentPlayer player) {
//		int rating = 0;
//		
//		if (player == CurrentPlayer.Max) {
//			rating = 1;
//		} else {
//			rating = -1;
//		}
//		
//		node.setRating(rating);
//		return rating;
//	}
//	
//	private int calculateMove(int count) {
//		int rating = -10;
//		int choice = 0;
//
//		boolean hasNoChild = true;
//
//		buildTree(count);
//
//		int oldRoot = _root.getData();
//		
//		// Fuer alle Kinder des Uebergebenen Knotens
//		for (Tree child : _root) {
//			// Der Kindknoten mit dem besten Rating wird gewaehlt
//			// da der Computer Max ist
//			if (child.getRating() > rating) {
//				rating = child.getRating();
//				choice = child.getData();
//				_root = child;
//				hasNoChild = false;
//			}
//		}
//		
//		// Sollte durch Alpha-Beta Pruning ein Node keine Kinder mehr habe
//		// Aber es sind noch welche vorhanden wird der Baum neu erstellt
//		if (hasNoChild) {
//			_root = null;
//			buildTree(count);
//			choice = calculateMove(count);
//		}
//		
//		// Ausgabe des gewaehlten Zuges
//
//		return (oldRoot - choice);
//	}
//}